﻿using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using System.Drawing;

namespace T3K.SketchEditor.Configuration {

    [Serializable]
    public class MenuItemConfig {

        private string _label;
        private string _command;
        private string _parameters;
        private string _image;
        private string _type;
        private MenuItemConfig[] _items = new MenuItemConfig[0];

        [XmlAttribute()]
        public string Label {
            get { return _label; }
            set { _label = value; }
        }

        [XmlAttribute()]
        public string Command {
            get { return _command; }
            set { _command = value; }
        }

        [XmlAttribute()]
        public string Parameters {
            get { return _parameters; }
            set { _parameters = value; }
        }

        [XmlAttribute()]
        public string Image {
            get { return _image; }
            set { _image = value; }
        }

        [XmlAttribute()]
        public string MenuType {
            get { return _type; }
            set { _type = value; }
        }

        public MenuItemConfig[] Items {
            get { return _items; }
            set {
                if (value == null)
                    _items = new MenuItemConfig[0];
                else
                    _items = value; 
            }
        }

    }

    [Serializable]
    public class MenuConfig : SettingsBase {

        private MenuItemConfig[] _items = new MenuItemConfig[0];

        public MenuItemConfig[] Items {
            get { return _items; }
            set { 
                if (value == null)
                    _items = new MenuItemConfig[0];
                else
                    _items = value; 

            }
        }

        protected MenuConfig() { }

        public MenuConfig(string configName) : base(configName) { }


        public void BuildMenu(ContextMenuStrip menu, EventHandler handler) {
            foreach (MenuItemConfig miConfig in this.Items)
                BuildMenu(menu, null, miConfig, handler);
        }

        public void BuildMenu(MenuStrip menu, EventHandler handler) {
            foreach (MenuItemConfig miConfig in this.Items)
                BuildMenu(menu, null, miConfig, handler);
        }

        private void BuildMenu(ContextMenuStrip menu, ToolStripMenuItem item, MenuItemConfig miConfig, EventHandler handler) {


            ToolStripItem nItem;

            if (miConfig.MenuType.Equals("separator"))
                nItem = new ToolStripSeparator();
            else {
                nItem = new ToolStripMenuItem();
                nItem.Tag = miConfig;
                nItem.Text = miConfig.Label;
            }

            if (miConfig.Image != null && miConfig.Image.Trim() != string.Empty) {

                Image image = T3K.SketchEditor.Core.EditorManager.Instance.GetImage(miConfig.Image);
                if (image != null)
                    nItem.Image = image;

                //if (miConfig.Image.ToLower().IndexOf("$embed:") > -1) {
                //    string[] tokens = miConfig.Image.Trim().Split(':');
                //    if (tokens.Length == 2) {
                //        string imageName = tokens[1];
                //        Assembly runningAssembly = Assembly.GetExecutingAssembly();
                //        Stream stream = runningAssembly.GetManifestResourceStream(
                //            string.Format("T3K.SSB.img.{0}", imageName));
                //        if (stream != null) {
                //            Bitmap img = new Bitmap(stream);
                //            nItem.Image = img;
                //        }
                //    }
                //}

            }

            nItem.Click += handler;

            foreach (MenuItemConfig subMiConfig in miConfig.Items) {
                ToolStripMenuItem nItemMn = nItem as ToolStripMenuItem;
                if (nItemMn != null)
                    BuildMenu(menu, nItemMn, subMiConfig, handler);
            }

            if (item == null)
                menu.Items.Add(nItem);
            else
                item.DropDownItems.Add(nItem);

        }

        private void BuildMenu(MenuStrip menu, ToolStripMenuItem item, MenuItemConfig miConfig, EventHandler handler) {

            ToolStripItem nItem;

            if (miConfig.MenuType.Equals("separator"))
                nItem = new ToolStripSeparator();
            else {
                nItem = new ToolStripMenuItem();
                nItem.Tag = miConfig;
                nItem.Text = miConfig.Label;
            }

            if (miConfig.Image != null && miConfig.Image.Trim() != string.Empty) {

                Image image = T3K.SketchEditor.Core.EditorManager.Instance.GetImage(miConfig.Image);
                if (image != null)
                    nItem.Image = image;

                //if (miConfig.Image.ToLower().IndexOf("$embed:") > -1) {
                //    string[] tokens = miConfig.Image.Trim().Split(':');
                //    if (tokens.Length == 2) {
                //        string imageName = tokens[1];
                //        Assembly runningAssembly = Assembly.GetExecutingAssembly();
                //        Stream stream = runningAssembly.GetManifestResourceStream(
                //            string.Format(".{0}", imageName));
                //        if (stream != null) {
                //            Bitmap img = new Bitmap(stream);
                //            nItem.Image = img;
                //        }
                //    }
                //}
            }

            nItem.Click += handler;

            if (miConfig.Command != null && miConfig.Command != string.Empty) {
                if (miConfig.Parameters != null && miConfig.Parameters != string.Empty)
                    nItem.Tag = string.Format("{0}/{1}", miConfig.Command, miConfig.Parameters);
                else
                    nItem.Tag = miConfig.Command;
            }

            foreach (MenuItemConfig subMiConfig in miConfig.Items) {
                ToolStripMenuItem nItemMn = nItem as ToolStripMenuItem;
                if (nItemMn != null)
                    BuildMenu(menu, nItemMn, subMiConfig, handler);
            }

            if (item == null)
                menu.Items.Add(nItem);
            else
                item.DropDownItems.Add(nItem);

        }


        public static MenuConfig FromMenuStrip (MenuStrip mStrip) {

            MenuConfig mConfig = new MenuConfig();
            mConfig.ConfigName = mStrip.Name;

            List<MenuItemConfig> subItemsConfig = new List<MenuItemConfig>();

            foreach (ToolStripItem mItem in mStrip.Items) {
                subItemsConfig.Add(BuildMenuItemConfig(mItem));
            }

            mConfig.Items = subItemsConfig.ToArray();

            return mConfig;

        }

        private static MenuItemConfig BuildMenuItemConfig (ToolStripItem mItem) {

            ToolStripMenuItem menuItem = mItem as ToolStripMenuItem;
            ToolStripSeparator separator = mItem as ToolStripSeparator;

            MenuItemConfig mItemConfig = new MenuItemConfig();

            if (separator != null) {
                mItemConfig.MenuType = "separator";
            } else
                mItemConfig.MenuType = "item";

            if (menuItem != null) {
                mItemConfig.Label = mItem.Text;
                string commandDef = mItem.Tag as string;
                if (commandDef != null) {
                    string[] commandTokens = commandDef.Split(new char[] {'/'}, 2, StringSplitOptions.RemoveEmptyEntries);
                    if (commandTokens.Length > 0)
                        mItemConfig.Command = commandTokens[0];
                    if (commandTokens.Length == 2)
                        mItemConfig.Parameters = commandTokens[1];
                }

                List<MenuItemConfig> subItemsConfig = new List<MenuItemConfig>();
                foreach (ToolStripItem subItem in menuItem.DropDownItems) {
                    subItemsConfig.Add(BuildMenuItemConfig(subItem));
                }
                if (subItemsConfig.Count > 0)
                    mItemConfig.Items = subItemsConfig.ToArray();
                
            }

            return mItemConfig;

        }

        public static MenuConfig Open(string configName) {
            return (MenuConfig)Open(ConfigFilePath(configName), typeof(MenuConfig));
        }

    }
}
